def efficientDataframe(filename,nbExpiry):
    import pandas as pd
    df = pd.read_csv(filename,index_col='date',na_values=["",''],delimiter=';',engine='c')
    return df
def maxDrawDown(priceList):
    import numpy as np
    i = np.argmax(np.maximum.accumulate(priceList)-priceList)
    j = np.argmax(priceList[:i]) 
    return ((priceList[j]/priceList[i])-1)*100
def movingAverage(prices,n):
    import numpy as np
    pricelist = np.asarray(prices)
    ret = np.cumsum(np.insert(pricelist,0,0))
    ret = (ret[n:] - ret[:-n])/n
    retList = list(ret)    
    for i in range(0,n-1):
        retList.insert(i,np.NaN)
    return np.asarray(retList)     
def exitDate(tradeDate,holdPer,commBool):
    year = int(tradeDate[0:4])
    month = int(tradeDate[5:7])
    day = int(tradeDate[8:10])
    if commBool:
        sugarexp = [3,5,7,10]
        if month in sugarexp:
            now = sugarexp.index(month)
            if now + holdPer>3:
                while holdPer>0:
                    if now == 3:
                        now = 0
                        year+=1
                    else:
                        now+=1
                    holdPer-=1   
            else:
                now += holdPer        
            day = 20
            month= sugarexp[now]
        else:
            while month not in sugarexp:
                if month==12:
                    month=3
                else:
                    month+=1
            now = sugarexp.index(month)
            if now + holdPer>3:
                while holdPer>0:
                    if now == 3:
                        now = 0
                        year+=1
                    else:
                        now+=1
                    holdPer-=1        
            else:
                now+=holdPer
            day = 20
            if now == 0:
                now =3
            else:
                now -= 1
            month= sugarexp[now]        
    else:
        if(day>20):
            day = 20
            if((month+holdPer) >12):
                year += 1
                month +=holdPer - 12 
            else:
                month+= holdPer
        else:
            day = 20
            if(month+holdPer-1>12):
                year += 1
                month += holdPer - 12
            else:
                month+=holdPer-1
    if month<10:
        monthstr = '0'+str(month)
    else:
        monthstr = str(month)    
    ret = str(year)+'-'+str(monthstr)+'-'+str(day)
    return ret
def timeToExit(date,exiter):
    if type(exiter) is int:
        return False
    yearDate = int(date[0:4])
    monthDate = int(date[5:7])
    dayDate = int(date[8:10])
    yearExit = int(exiter[0:4])
    monthExit = int(exiter[5:7])
    dayExit = int(exiter[8:10])
    ret = False
    if yearDate >= yearExit and monthDate >= monthExit:
        if dayDate>=dayExit:
            ret = True
    return ret
def lockNHoldEfficient(dataF,nbper,ratio,ticker,commBool):
    import numpy as np
    import matplotlib.pyplot as plt
    dates = np.asarray(dataF.index.values)
    spot = dataF[ticker+str(0)].values
    contractMonth = dataF[ticker+str(nbper-1)].values
    result = []
    price = 0
    inTrade = False
    for d in range(0,len(dates)):
        if not inTrade:
            inTrade = True
            price = contractMonth[d]
            tradeDate = dates[d]
            exitTradeDate = exitDate(tradeDate,nbper,commBool)
        else:
            if (timeToExit(dates[d],exitTradeDate) and not timeToExit(dates[d-1],exitTradeDate)):
                inTrade = False
                d-=1
        result.append(price)
    
    res = spot-ratio*(spot-np.asarray(result))
    printResults(spot,res)
    x = np.cumsum(np.ones(len(spot)))
    plt.figure(1)
    plt.gca().set_color_cycle(['blue', 'green', 'red', 'purple'])
    plt.plot(x,spot*100,x,np.asarray(result)*100,x,res*100)
    plt.legend(["Spot Prices","Locked Prices","Hedged prices using "+str(nbper)+"th contract"], loc = 'upper right')
    plt.title("Spot prices vs Hedged prices " + dates[0] + " to " + dates[len(dates)-1])
    plt.show()
    return 0
def movingAvgEfficient(dataF,ticker,upPeriod,downPeriod,ratio,MA,commBool):
    import numpy as np,matplotlib.pyplot as plt
    dates = np.asarray(dataF.index.values)
    spot = dataF[ticker+str(0)].values
    ma = movingAverage(spot,MA)
    inTrade = False
    tradePrices = []
    for d in range(0,len(dates)):
        if not inTrade:
            inTrade = True
            tradeDate = dates[d]
            if spot[d]>ma[d]:
                tradePrice = dataF[ticker+str(upPeriod)][dates[d]]
                exitTradeDate =exitDate(tradeDate,upPeriod,commBool)
            else:
                tradePrice = dataF[ticker+str(downPeriod)][dates[d]]
                exitTradeDate =exitDate(tradeDate,downPeriod,commBool)
        else:
            if timeToExit(dates[d],exitTradeDate) and not timeToExit(dates[d-1],exitTradeDate):
                d-=1
                inTrade = False
        tradePrices.append(tradePrice)
    ret = spot-ratio*(spot-np.asarray(tradePrices))
    printResults(spot,ret)
    x = np.cumsum(np.ones(len(spot)))
    plt.figure(1)
    plt.gca().set_color_cycle(['blue', 'green', 'red', 'purple'])
    plt.plot(x,spot*100,x,np.asarray(tradePrices)*100,x,ma*100,x,ret*100)
    plt.legend(["Spot Price","Locked Prices","Moving Average "+str(MA)+' days','Resulting Prices'], loc = 'upper right')
    plt.title("Spot prices vs Hedged prices " + dates[0] + " to " + dates[len(dates)-1])
    plt.show()
    return 0
def printResults(spotPrices,resultPrices):
    import numpy as np
    resReturns = (((resultPrices[1:]/resultPrices[:-1])-1)*100)
    spotReturns= (((spotPrices[1:]/spotPrices[:-1])-1)*100)
    print('******************************************************************')
    print('*                       VITAL STATS OF BACKTEST                  *')
    print('*                        HEDGED    |     Spot                    *')
    print('******************************************************************')
    print('Monthly 99% VaR       | '+"{0:.4f}".format(np.percentile(resReturns,1)*np.sqrt(20))+'%        '+"{0:.4f}".format(np.percentile(spotReturns,1)*np.sqrt(20))+'%')
    print('Annualized Volatility |  '+"{0:.4f}".format(np.std(resReturns)*np.sqrt(252))+     '%        '+"{0:.4f}".format(np.std(spotReturns)*np.sqrt(252))+'%')
    print('Max Drawdown %        |  '+"{0:.4f}".format(maxDrawDown(resultPrices))+              '%        '+"{0:.4f}".format(maxDrawDown(spotPrices))+'%')
    print('******************************************************************')
    return 0
                 
                    
                    
                
                
                
            
            
            
            
            
    
    
    


    
    



